/**
 * 请求ID中间件
 * 为每个请求生成唯一的correlation_id，并传递给日志系统
 */

const { getLogger } = require('../logger');
const logger = getLogger('middlewares.requestIdMiddleware');
const { generateCorrelationId } = require('../logger/utils');

/**
 * 请求ID中间件函数
 * 从请求头获取或生成correlation_id，并设置到请求对象和全局变量中
 */
const requestIdMiddleware = (req, res, next) => {
  try {
    // 尝试从请求头获取correlation_id（支持多种常见的头名称）
    const correlationId = req.headers['x-correlation-id'] || 
                         req.headers['correlation-id'] ||
                         req.headers['x-request-id'] ||
                         req.headers['request-id'] ||
                         generateCorrelationId();
    
    // 设置到请求对象
    req.correlationId = correlationId;
    
    // 设置到响应头，方便客户端跟踪
    res.setHeader('X-Correlation-ID', correlationId);
    
    // 设置到全局变量，供logger使用
    global.correlationId = correlationId;
    
    // 记录请求开始（可选）
    logger.debug('请求开始', {
      method: req.method,
      url: req.originalUrl,
      ip: req.ip,
      correlationId
    });
    
    // 请求结束时清理全局变量
    const originalEnd = res.end;
    res.end = function() {
      // 记录请求结束（可选）
      logger.debug('请求结束', {
        method: req.method,
        url: req.originalUrl,
        status: res.statusCode,
        correlationId
      });
      
      // 调用原始的end方法
      originalEnd.apply(this, arguments);
      
      // 延迟清理，避免异步日志操作丢失correlation_id
      process.nextTick(() => {
        if (global.correlationId === correlationId) {
          delete global.correlationId;
        }
      });
    };
    
    next();
  } catch (error) {
    logger.error('请求ID中间件错误', { error: error });
    // 即使出错也要继续处理请求
    next();
  }
};

module.exports = requestIdMiddleware;